package com.cy.cur;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class CasDemo_3 {

    static volatile int count = 0;

    public static void add() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(5);
        // count++;
        int expectCount;

        while (!compareAndSwap(
                (expectCount = getCount()),
                expectCount + 1
        )) {
        }
    }

     // CAS 比较并替换
    public static synchronized boolean compareAndSwap(int expectCount, int newCount) {
        // 这里 count 其实用原始值也是没问题的  这样写更多是封装性的考虑
        if (getCount() == expectCount) {
            count = newCount;
            return true;
        }
        return false;
    }

    public static int getCount() {
        return count;
    }


    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();

        int threadSize = 100;

        CountDownLatch countDownLatch = new CountDownLatch(threadSize);
        for (int i = 0; i < threadSize; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int j = 0; j < 10; j++) {
                            add();
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    } finally {
                        countDownLatch.countDown();
                    }
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println(count);
        System.out.println(System.currentTimeMillis() - start);
    }

}
